import { nextTick } from 'vue'
import { defineStore } from 'pinia'
import { browserChannel, getZIndex } from '@/utils/utils'
import { BrowserChannelType } from '@/hooks/browserHooks'
import type { DeskAppComponent } from '@/stores/systemApp/deskApp'

interface IComponentData {
  [key: string]: unknown
}

type SetTaskPatch = Partial<Omit<IRunningTasksList, 'id' | 'component' | 'isSystemTopBar'>>

export interface IRunningTasksList {
  readonly id: string // 单一ID
  readonly component: DeskAppComponent // 任务弹窗内容的插入的组件
  readonly isSystemTopBar: boolean // 是否需要顶部拖动条
  title: string // 名称 会出现在顶部导航栏 和 任务栏图标中
  isDrag: boolean // 是否正在拖动
  icon: string // 任务的图标
  isFull: boolean // 是否最大化状态
  isMax: boolean // 是否最大化状态
  isMin: boolean // 是否最小化状态
  isResize: boolean // 是否可以改变大小
  x: number // 任务窗口位置 X轴
  y: number // 任务窗口位置 Y轴
  endX: number // 任务窗口拖动最后所在位置位置 X轴 用于隐藏等事件后 回归原始位置
  endY: number // 任务窗口拖动最后所在位置位置 Y轴 用于隐藏等事件后 回归原始位置
  width: number // 任务窗口宽度
  height: number // 任务窗口高度
  minSize: number[] // 任务窗口最小大小
  maxSize: number[] // 任务窗口最大大小
  isChecked: boolean // 是否窗口被选中
  tray: boolean // 是否存在任务系统托盘图标
  trayIcon: string // 任务系统托盘图标
  isTray: boolean // 是否处于任务系统托盘中状态
  taskBar: boolean // 是否任务栏
  isTaskBar: boolean // 是否任务栏
  componentData?: IComponentData // 任务自身组件需要的数据
}

export interface IRunningTasks {
  readonly appId: DeskAppComponent
  list: IRunningTasksList[]
}

export interface IRunningTasksStore {
  runningTasks: IRunningTasks[]
  tasksIdList: string[]
  currentTaskAppId: DeskAppComponent | null
}

export const useRunningTasksStore = defineStore('RunningTask', {
  state: (): IRunningTasksStore => {
    return {
      runningTasks: [],
      tasksIdList: [],
      currentTaskAppId: null
    }
  },
  actions: {
    // 找到某个任务
    findTask(appId: string, id: string): IRunningTasksList | null {
      const findAppIdIndex = this.runningTasks.findIndex((item) => item.appId === appId)
      if (findAppIdIndex >= 0) {
        const findIdIndex = this.runningTasks[findAppIdIndex].list.findIndex((item) => item.id === id)
        if (findIdIndex >= 0) return this.runningTasks[findAppIdIndex].list[findIdIndex]
      }
      return null
    },
    // 找到某个任务的索引
    findTaskIndex(appId: string, id: string): number[] {
      const findAppIdIndex = this.runningTasks.findIndex((item) => item.appId === appId)
      if (findAppIdIndex >= 0) {
        const findIdIndex = this.runningTasks[findAppIdIndex].list.findIndex((item) => item.id === id)
        if (findIdIndex >= 0) return [findAppIdIndex, findIdIndex]
      }
      return [-1, -1]
    },
    // 批量设置任务
    setTaskPatch(appId: string, id: string, task: SetTaskPatch) {
      const indexList = this.findTaskIndex(appId, id)
      if (this.runningTasks?.[indexList[0]]?.list?.[indexList[1]]) {
        if (task.componentData) {
          this.runningTasks[indexList[0]].list[indexList[1]].componentData = {
            ...this.runningTasks[indexList[0]].list[indexList[1]].componentData,
            ...task.componentData
          }
          delete task.componentData
        }
        this.runningTasks[indexList[0]].list[indexList[1]] = {
          ...this.runningTasks[indexList[0]].list[indexList[1]],
          ...task
        }
      }
    },
    // 把所有任务的某个值设置为相同
    resetRunningTaskKey<T extends keyof IRunningTasksList>(key: T, value: IRunningTasksList[T]) {
      this.runningTasks.forEach((item) => {
        item.list.forEach((child) => {
          child[key] = value
        })
      })
    },
    // 新键任务
    async createNewTask(data: IRunningTasks) {
      const findAppIdIndex = this.runningTasks.findIndex((item) => item.appId === data.appId)
      if (findAppIdIndex >= 0) {
        this.runningTasks[findAppIdIndex].list.push(...data.list)
      } else {
        this.runningTasks.push(data)
      }
      await nextTick()
      this.checkedCurrentTask(data.appId, data.list[data.list.length - 1].id, true)
    },
    // 设置任务位置
    setTaskPosition(appId: string, id: string, x: number, y: number) {
      const currentTask = this.findTask(appId, id)
      if (currentTask) {
        currentTask.x = x
        currentTask.y = y
      }
    },
    // 设置任务大小
    setTaskSize(appId: string, id: string, width: number, height: number) {
      const currentTask = this.findTask(appId, id)
      if (currentTask) {
        currentTask.width = width
        currentTask.height = height
      }
    },
    // 关闭任务
    closeTask(appId: string, id: string) {
      const findAppIdIndex = this.runningTasks.findIndex((item) => item.appId === appId)
      if (findAppIdIndex >= 0) {
        this.runningTasks[findAppIdIndex].list = this.runningTasks[findAppIdIndex].list.filter((item) => item.id !== id)
        if (!this.runningTasks[findAppIdIndex].list.length) {
          this.runningTasks = this.runningTasks.filter((item) => item.appId !== appId)
        }
      }
      browserChannel.postMessage({ type: BrowserChannelType.refresh })
    },
    // 最大化 / 最小化 任务
    setMinMaxTask(appId: DeskAppComponent, id: string, isMax = false) {
      const currentTask = this.findTask(appId, id)
      this.currentTaskAppId = appId
      if (currentTask) currentTask.isMax = isMax || !currentTask.isMax
    },
    // 选中某个任务
    checkedCurrentTask(appId: DeskAppComponent, id: string, isChecked: boolean = true) {
      this.resetRunningTaskKey('isChecked', false)
      const dom = document.querySelector(`div[data-task-id="${id}"]`) as HTMLElement
      if (dom) dom.style.zIndex = `${getZIndex()}`
      const currentTask = this.findTask(appId, id)
      this.currentTaskAppId = appId
      if (currentTask) {
        currentTask.isChecked = isChecked
        this.setTaskPosition(appId, id, currentTask.endX, currentTask.endY)
        this.setTaskToTray(appId, id, false)
      }
    },
    // 最小化任务
    setTaskToMin(appId: string, id: string, isMin: boolean) {
      const currentTask = this.findTask(appId, id)
      if (currentTask) {
        currentTask.isMin = isMin
        if (isMin) currentTask.isChecked = false
      }
    },
    // 设置任务内置方法
    setComponentData(appId: string, id: string, data: IComponentData) {
      const currentTask = this.findTask(appId, id)
      if (currentTask) currentTask.componentData = { ...currentTask.componentData, ...data }
    },
    // 隐藏到托盘
    setTaskToTray(appId: string, id: string, isTray: boolean) {
      const currentTask = this.findTask(appId, id)
      if (currentTask) {
        currentTask.isTray = isTray
        currentTask.taskBar = !isTray
      }
    }
  },
  persist: true
})
